#ifndef _EPOLL_SERVLET_H
#define _EPOLL_SERVLET_H
#include "IServlet.h"
#include <thread>
#include <list>
#include <mutex>
#include <condition_variable>


class EpollServerServlet;
class EpollWorkSession;
class IWorkNode {
public:
    IWorkNode();
    void putTask(int socket);
    virtual void v_PrePutTask(EpollWorkSession *session) = 0;
    virtual void v_Action() = 0;
    void stop();
    void start();
    void wait();
    virtual bool v_CheckNeedWork() = 0;
    void run();
    virtual ~IWorkNode();
public:
   
    std::mutex my_mutex;
    std::condition_variable my_cond;
    int balance = 0;
    std::thread *thr = NULL;
    bool isRun = true;
    EpollServerServlet *server = NULL;
    std::list<ISession *> sessions;
   
};


class EpollClientServlet : public IServlet
{
public:
    virtual void on(SERVLET_STATUS type, std::function<int(ISession *session, void *, int)> handler);
    virtual void request(const void *data, int len);
    virtual void start();
    virtual void wait();
    virtual void stop();
    virtual void onLoad(INode *node);
    virtual void onUnload();
    virtual void onMessage(ISession *session, void *data, int size);
    virtual void onState(SERVLET_STATUS status, ISession *session, int code);
    virtual ~EpollClientServlet();
public:
    bool isRun = true;
    int conn_fd = -1;
    int port = 0;
    std::string ip;
    void *_thread = NULL;
    virtual void recvthreadLogic(int socket);
    void threadLogic();

    std::map<int,std::vector<std::function<int(ISession *,void*,int)> > >  msgidHandlers;
};

class WorkNode;
class EpollServerServlet : public IServlet
{
public:
    virtual void on(SERVLET_STATUS type, std::function<int(ISession *session, void *, int)> handler);
    virtual void request(const void *data, int len);
    virtual void start();
    virtual void wait();
    virtual void stop();
    virtual void onLoad(INode *node);
    virtual void onUnload();
    virtual void onMessage(ISession *session, void *data, int size);
    virtual void onState(SERVLET_STATUS status, ISession *session, int code);
    virtual ~EpollServerServlet();

    void putToWorkThread(int socket);
    void acceptThreadLogic();
    WorkNode *workList = NULL;
    WorkNode *currLocation = NULL;
    std::thread *listenThread = NULL;

    int serverSocket = -1;
    int listenEpollHandler = -1;
    bool isRun = true;
    int port = 12345;
};

#endif // _EPOLL_SERVLET_H